package ru.amse.podolsky.fractalarch.ui.gui;

/**
 *@author Алексей
 */

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import java.io.File;
import javax.swing.filechooser.FileNameExtensionFilter;
import ru.amse.podolsky.fractalarch.model.IParams.fractalTypes;
import ru.amse.podolsky.fractalarch.model.IParams.imageTypes;
import ru.amse.podolsky.fractalarch.model.Options;

public class Actions {

    // <editor-fold defaultstate="collapsed" desc="Exit Action">
    public static class exitAction extends AbstractAction{
        public exitAction() {
            super("Exit Action");
            this.putValue(NAME, "Exit");
            this.putValue(SHORT_DESCRIPTION, "Exit from program");
        }

        public void actionPerformed(ActionEvent evt){
            System.exit(0);
        }
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Open File Action">
    public static class openFileAction extends AbstractAction{
        private GUI gui = null;
        
        private openFileAction() {
            this.putValue(NAME, "Open File");
            this.putValue(SHORT_DESCRIPTION, "Choosen file to open");
        }

        public openFileAction(GUI gui){
            this.gui = gui;
            this.putValue(NAME, "Open File");
            this.putValue(SHORT_DESCRIPTION, "Choosen file to open");
        }

        public void actionPerformed(ActionEvent evt){            
            JFileChooser choose = new JFileChooser(gui.getPath());
            choose.setFileFilter(new FileNameExtensionFilter("Fractal Images", Options.getFractalExtension()));
            choose.setFileFilter(new FileNameExtensionFilter("Images", Options.getExtensions()));
            int result = choose.showDialog(choose, "Select File");
            if (result == JFileChooser.APPROVE_OPTION){
                this.gui.setPath(choose.getSelectedFile().getAbsolutePath());
                this.gui.setLabel("File " + choose.getSelectedFile().getAbsolutePath() + " opened");
            }
        }
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Save File Action">
    public static class saveFileAsAction extends AbstractAction{
        private GUI gui = null;

        private saveFileAsAction() {
            this.putValue(NAME, "Save As");
            this.putValue(SHORT_DESCRIPTION, "Save file with name, defined by you");
        }

        public saveFileAsAction(GUI gui){
            this.gui = gui;
            this.putValue(NAME, "Save As");
            this.putValue(SHORT_DESCRIPTION, "Save file with name, defined by you");
        }

        public void actionPerformed(ActionEvent evt){
            if(isVoid(this.gui)){
                return;
            }

            JFileChooser save = new JFileChooser(gui.getPath());
            save.setFileFilter(new FileNameExtensionFilter("Fractal Images", Options.getFractalExtension()));
            save.setFileFilter(new FileNameExtensionFilter("Images", Options.getExtensions()));
            int result = save.showDialog(save, "Save As");
            if (result == JFileChooser.APPROVE_OPTION)
            {
                this.gui.setLabel("Wait while file is saved");
                this.gui.saveAs(save.getSelectedFile().getAbsolutePath());
                this.gui.setLabel("File has been saved");
            }
        }
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Close File Action">
    public static class closeFileAction extends AbstractAction{
        private GUI gui = null;

        public closeFileAction() {
            this.putValue(NAME, "Close File");
            this.putValue(SHORT_DESCRIPTION, "Close current file");
        }

        public closeFileAction(GUI gui){
            this.gui = gui;
            this.putValue(NAME, "Close File");
            this.putValue(SHORT_DESCRIPTION, "Close current file");
        }

        public void actionPerformed(ActionEvent evt){
            if(isVoid(this.gui)){
                return;
            }

            this.gui.setPath("");
            this.gui.setLabel("File closed");
        }


    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Compress Action">
    public static class compressAction extends AbstractAction{
        GUI gui = null;

        public compressAction() {
            this.putValue(NAME, "Compress");
            this.putValue(SHORT_DESCRIPTION, "Show Compress dialog");
            this.putValue(LARGE_ICON_KEY, new javax.swing.ImageIcon(getClass().getResource("/ru/amse/podolsky/fractalarch/resourses/Compress.png")));
        }

        public compressAction(GUI gui) {
            this.putValue(NAME, "Compress");
            this.putValue(SHORT_DESCRIPTION, "Show Compress dialog");
            this.putValue(LARGE_ICON_KEY, new javax.swing.ImageIcon(getClass().getResource("/ru/amse/podolsky/fractalarch/resourses/Compress.png")));
            this.gui = gui;
        }

        public void actionPerformed(ActionEvent evt){
            if(isVoid(this.gui)){
                return;
            }

            if(extensionIsImage(this.gui.getPath())){
                File file = new File("D:\\Fractal Archivaitor\\temp.fah");
                this.gui.setLabel("Wait while file is compressed");
                this.gui.saveAs(file);
                this.gui.setLabel("Compression done");
            }else{
                JOptionPane.showMessageDialog(null, "You try to compress the image, that is allready compressed.", "Compression warning", JOptionPane.PLAIN_MESSAGE);
            }
        }
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Decompress Action">
    public static class decompressAction extends AbstractAction{
        GUI gui = null;

        public decompressAction() {
            this.putValue(NAME, "Decompress");
            this.putValue(SHORT_DESCRIPTION, "Show Decompress dialog");
        }

         public decompressAction(GUI gui) {
            this.putValue(NAME, "Decompress");
            this.putValue(SHORT_DESCRIPTION, "Show Decompress dialog");
            this.gui = gui;
        }

        public void actionPerformed(ActionEvent evt){
            if(isVoid(this.gui)){
                return;
            }

            if(extensionIsFractal(this.gui.getPath())){
                File file = new File("d:\\Fractal Archivaitor\\temp.bmp");
                this.gui.setLabel("Wait while file is decompressed");
                this.gui.saveAs(file);
                this.gui.setLabel("Decompression done");
            }else{
                JOptionPane.showMessageDialog(null, "You try to decompress the archiv, that is allready decompressed.", "Compression warning", JOptionPane.PLAIN_MESSAGE);
            }
        }
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Positive Zoom Action">
    public static class positivZoomAction extends AbstractAction{
        public positivZoomAction() {
            this.putValue(NAME, "Zoom +");
            this.putValue(SHORT_DESCRIPTION, "Enlarge image");
            this.putValue(LARGE_ICON_KEY, new javax.swing.ImageIcon(getClass().getResource("/ru/amse/podolsky/fractalarch/resourses/zoom+.png")));
        }

        public void actionPerformed(ActionEvent evt){
            JOptionPane.showMessageDialog(null, "You clicked \"Positive Zoom\" menu item", "Positive Zoom", JOptionPane.INFORMATION_MESSAGE);
        }
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Negative Zoom Action">
    public static class negativZoomAction extends AbstractAction{
        public negativZoomAction() {
            this.putValue(NAME, "Zoom -");
            this.putValue(SHORT_DESCRIPTION, "Reduce image");
            this.putValue(LARGE_ICON_KEY, new javax.swing.ImageIcon(getClass().getResource("/ru/amse/podolsky/fractalarch/resourses/zoom-.png")));
        }

        public void actionPerformed(ActionEvent evt){
            JOptionPane.showMessageDialog(null, "You clicked \"Negativ Zoom\" menu item", "Negativ Zoom", JOptionPane.INFORMATION_MESSAGE);
        }
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Previous Action">
    public static class previousAction extends AbstractAction{
        GUI gui = null;

        public previousAction() {
            this.putValue(NAME, "Previous image");
            this.putValue(SHORT_DESCRIPTION, "Select previous image");
            this.putValue(LARGE_ICON_KEY, new javax.swing.ImageIcon(getClass().getResource("/ru/amse/podolsky/fractalarch/resourses/previous.png")));
        }

        public previousAction(GUI gui) {
            this.putValue(NAME, "Previous image");
            this.putValue(SHORT_DESCRIPTION, "Select previous image");
            this.putValue(LARGE_ICON_KEY, new javax.swing.ImageIcon(getClass().getResource("/ru/amse/podolsky/fractalarch/resourses/previous.png")));
            this.gui = gui;
        }

        public void actionPerformed(ActionEvent evt){
            if(isVoid(this.gui)){
                return;
            }

            File file = new File(gui.getPath());
            File [] files = file.getParentFile().listFiles();
            int length = files.length;
            int i = 0;
            while (!files[i].getAbsolutePath().equals(file.getAbsolutePath())){
                i++;
            }
            for (int j = i-1; j >= 0; j--) {
                String name = files[j].getAbsolutePath();
                if(extensionIsImage(name) || extensionIsFractal(name)){
                    this.gui.setPath(name);
                    this.gui.setLabel(name);
                    return;
                }
            }
            for (int j = length - 1; j > i; j--) {
                String name = files[j].getAbsolutePath();
                if(extensionIsImage(name) || extensionIsFractal(name)){
                    this.gui.setPath(name);
                    this.gui.setLabel(name);
                    return;
                }
            }
        }
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Next Action">
    public static class nextAction extends AbstractAction{
         GUI gui = null;

        public nextAction() {
            this.putValue(NAME, "Next image");
            this.putValue(SHORT_DESCRIPTION, "Select next image");
            this.putValue(LARGE_ICON_KEY, new javax.swing.ImageIcon(getClass().getResource("/ru/amse/podolsky/fractalarch/resourses/next.png")));
        }

        public nextAction(GUI gui) {
            this.gui = gui;
            this.putValue(NAME, "Next image");
            this.putValue(SHORT_DESCRIPTION, "Select next image");
            this.putValue(LARGE_ICON_KEY, new javax.swing.ImageIcon(getClass().getResource("/ru/amse/podolsky/fractalarch/resourses/next.png")));
        }

        public void actionPerformed(ActionEvent evt){
            if(isVoid(this.gui)){
                return;
            }

            File file = new File(gui.getPath());
            File [] files = file.getParentFile().listFiles();
            int length = files.length;
            int i = 0;
            while (!files[i].getAbsolutePath().equals(file.getAbsolutePath())){
                i++;
            }
            for (int j = i+1; j < length; j++) {
                String name = files[j].getAbsolutePath();
                if(extensionIsImage(name) || extensionIsFractal(name)){
                    this.gui.setPath(name);
                    this.gui.setLabel(name);
                    return;
                }
            }
            for (int j = 0; j < i; j++) {
                String name = files[j].getAbsolutePath();
                if(extensionIsImage(name) || extensionIsFractal(name)){
                    this.gui.setPath(name);
                    this.gui.setLabel(name);
                    return;
                }
            }
        }
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="About Action">
    public static class aboutAction extends AbstractAction{
        public aboutAction() {
            this.putValue(NAME, "About");
            this.putValue(SHORT_DESCRIPTION, "Show About message");
        }

        public void actionPerformed(ActionEvent evt){
            JOptionPane.showMessageDialog(null, "You clicked \"About\" menu item", "About", JOptionPane.INFORMATION_MESSAGE);
        }
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Utils">
    private static boolean extensionIsFractal(String ext){
            int length = ext.length();
            char[] ch = ext.toCharArray();
            char[] newch = new char[length];
            int i = 1;
            while(length - i > 0 && ch[length - i] != '.'){
                newch[i] = ch[length - i];
                i++;
            }

            StringBuilder result = new StringBuilder();

            if(i == 4){
                 result.append(newch[3]);
                 result.append(newch[2]);
                 result.append(newch[1]);
            }else{
                result.append(newch[4]);
                result.append(newch[3]);
                result.append(newch[2]);
                result.append(newch[1]);
            }

            String res = result.toString();

            return fractalTypes.include(res);
    }

    private static boolean extensionIsImage(String ext){
        int length = ext.length();
        char[] ch = ext.toCharArray();
        char[] newch = new char[length];
        int i = 1;
        while(length - i > 0 && ch[length - i] != '.'){
            newch[i] = ch[length - i];
            i++;
        }

        StringBuilder result = new StringBuilder();

        if(i == 4){
             result.append(newch[3]);
             result.append(newch[2]);
             result.append(newch[1]);
        }else{
            result.append(newch[4]);
            result.append(newch[3]);
            result.append(newch[2]);
            result.append(newch[1]);
        }

        String res = result.toString();

        return imageTypes.include(res);
    }

    private static boolean isVoid(GUI gui){
        if(gui.getPath().equals("")){
            JOptionPane.showMessageDialog(null, "You try to do something on the void image. Please select image and try again", "Warning", JOptionPane.WARNING_MESSAGE);
            return true;
        }
        return false;
    }
    // </editor-fold>
}
